home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / indx18eu.zip / INDEXEDF.PAS < prev    next >
Pascal/Delphi Source File  |  1991-03-20  |  22KB  |  917 lines

  1. UNIT IndexedFiles ;
  2.  
  3.                              INTERFACE
  4.  
  5.  
  6.  
  7. {
  8.  
  9.     ***********************************************************************
  10.  
  11.     AUTHOR    :  Thomas E. Jenkins, Jr.
  12.  
  13.     VERSION   :  1.5           10 JAN 1991
  14.  
  15.     CONTACT   :  BITNET   :  C0361 @ UNIVSCVM
  16.                  INTERNET :  C0361 @ UNIVSCVM.CSD.SCAROLINA.EDU
  17.                  S-MAIL   :  Tom Jenkins
  18.                              9732 Windsor Lake Blvd.
  19.                              Columbia, SC 29223
  20.                  Voice    :  (803) 777-6666  ( Ask for Tom Jenkins )
  21.  
  22.     ***********************************************************************
  23.  
  24.       THIS MODULE:
  25.  
  26.             UNIT :  IndexedFiles          PC :  INDEXEDF.PAS
  27.  
  28.       USES :
  29.  
  30.             UNIT :  Files                 PC :  FILES   .PAS
  31.  
  32.  
  33.     ***********************************************************************
  34.  
  35.     This unit will index any record you design.  The only draw back is that
  36.     the very first element of your record MUST be a string [ 10 ] .  This is
  37.     the index.  You must supply a unique index here to insert a new record,
  38.     or simply enter an existing index to replace the record in the indexed
  39.     file.
  40.  
  41.     There are replacements to the standard turbo file procedures and functions
  42.     to deal with the index files.  There is a new file type exported by this
  43.     unit as well.
  44.  
  45.     Here is an example of how to create a index file:
  46.  
  47.     Define record with index.
  48.     Declare variable of type IFile.
  49.     Call AssignIndexed with IFile variable and file name.
  50.     Call ReWriteIndexed with IFile
  51.  
  52.     And now you have an indexed file!  See READ.ME file for more information.
  53.  
  54.     ReadIndexed and WriteIndexed will place data in your file.  The indexing
  55.     is up to you, but the index file is automatic and requires no ( read DO
  56.     NOT ) tampering!  See READ.ME file for more information.
  57.  
  58.     There is an exporteded variable:
  59.  
  60.        The type is WORD, fileError, set to 0.  This variable is updated
  61.        with one of the constants with this unit.  The variable IS NOT reset by
  62.        the unit until a new unit routine is called.
  63.  
  64.     There are also several constants exported by the unit.  See the READ.ME
  65.     file for more information.
  66.  
  67.  
  68. }
  69.  
  70.  
  71.  
  72.  
  73.  
  74. CONST
  75.        NO_ERROR                                  = 0 ;
  76.  
  77. CONST
  78.        NOT_ENOUGH_MEMORY                         = 1 ;
  79.  
  80. CONST
  81.        READ_LESS_BYTES_THAN_EXPECTED             = 2 ;
  82.  
  83. CONST
  84.        INDEX_NOT_FOUND                           = 3 ;
  85.  
  86. CONST
  87.        LESS_BYTES_WRITTEN_THAN_EXPECTED          = 4 ;
  88.  
  89. CONST
  90.        INVALID_FILE_NAME                         = 5 ;
  91.  
  92.  
  93.  
  94.  
  95.  
  96. TYPE
  97.        IndexStr                                  = STRING [ 010 ] ;
  98.  
  99.        IFile                                     = RECORD
  100.  
  101.          baseFile                                : FILE ;
  102.          indexFile                               : FILE ;
  103.  
  104.          fileName                                : STRING ;
  105.  
  106.        END ;  {  IFile  }
  107.  
  108.  
  109. TYPE
  110.        IndexType                                 = RECORD
  111.  
  112.          index                                   : IndexStr ;
  113.          position                                : LONGINT ;
  114.  
  115.        END ;  {  IndexType  }
  116.  
  117.  
  118.  
  119.  
  120.  
  121. VAR
  122.        fileError                                 : WORD ;
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  PROCEDURE   ReadIndexed ( VAR f                 : IFile ;
  129.                            VAR buffer                   ;
  130.                                size              : WORD ) ;
  131.  
  132.  PROCEDURE   WriteIndexed ( VAR f                : IFile ;
  133.                             VAR buffer                  ;
  134.                                 size             : WORD ) ;
  135.  
  136.  PROCEDURE   DeleteIndexed ( VAR f               : IFile ;
  137.                              VAR buffer          ;
  138.                                  size            : WORD ) ;
  139.  
  140.  PROCEDURE   ResetIndexed ( VAR f                : IFile ) ;
  141.  
  142.  PROCEDURE   ReWriteIndexed ( VAR f              : IFile ) ;
  143.  
  144.  PROCEDURE   CloseIndexed ( VAR f                : IFile ) ;
  145.  
  146.  FUNCTION    FilePosIndexed ( VAR f              : IFile ;
  147.                                   size           : WORD )
  148.                                                  : LONGINT ;
  149.  
  150.  PROCEDURE   AssignIndexed ( VAR f               : IFile ;
  151.                                  indexFile       : STRING ) ;
  152.  
  153.  FUNCTION    FileSizeIndexed ( VAR f             : IFile ;
  154.                                    size          : WORD )
  155.                                                  : LONGINT ;
  156.  
  157.  FUNCTION    IndexFileSize ( VAR f               : FILE )
  158.                                                  : LONGINT ;
  159.  
  160.  PROCEDURE   IndexSeek ( VAR f                   : FILE ;
  161.                              position            : LONGINT ) ;
  162.  
  163.  PROCEDURE   IndexRead ( VAR f                   : FILE ;
  164.                          VAR tempIndex           : IndexType ) ;
  165.  
  166.  FUNCTION    IndexedError (     errorNum         : WORD )
  167.                                                  : STRING ;
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.                            IMPLEMENTATION
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181. USES
  182.        DOS ,
  183.        CRT ,
  184.        Files ;
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  FUNCTION    IndexFileSize ( VAR f               : FILE )
  191.                                                  : LONGINT ;
  192.  
  193.    BEGIN  {  IndexFileSize  }
  194.  
  195.      IndexFileSize := FileSize ( f ) DIV SizeOf ( IndexType ) ;
  196.  
  197.    END ;  {  IndexFileSize  }
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  PROCEDURE   IndexReset ( VAR i                  : FILE ) ;
  204.  
  205.    BEGIN  {  IndexReset  }
  206.  
  207.      Reset ( i , 1 ) ;
  208.  
  209.    END ;  {  IndexReset  }
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  PROCEDURE   IndexSeek ( VAR f                   : FILE ;
  216.                              position            : LONGINT ) ;
  217.  
  218.    BEGIN  {  IndexSeek  }
  219.  
  220.      Seek ( f , ( position * SizeOf ( IndexType ) ) ) ;
  221.  
  222.    END ;  {  IndexSeek  }
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  PROCEDURE   IndexRead ( VAR f                   : FILE ;
  229.                          VAR tempIndex           : IndexType ) ;
  230.  
  231.   VAR
  232.        numRead                                   : WORD ;
  233.  
  234.    BEGIN  {  IndexRead  }
  235.  
  236.      BlockRead ( f , tempIndex , SizeOf ( IndexType ) , numRead ) ;
  237.  
  238.      IF ( numRead < SizeOf ( IndexType ) )
  239.       THEN
  240.          fileError := READ_LESS_BYTES_THAN_EXPECTED ;
  241.  
  242.    END ;  {  IndexRead  }
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  PROCEDURE   IndexWrite ( VAR f                  : FILE ;
  249.                               index              : IndexType ) ;
  250.   VAR
  251.        numWritten                                : WORD ;
  252.  
  253.    BEGIN  {  IndexWrite  }
  254.  
  255.      BlockWrite ( f , index , SizeOf ( IndexType ) , numWritten ) ;
  256.  
  257.      IF ( numWritten < SizeOf ( IndexType ) )
  258.       THEN
  259.          fileError := LESS_BYTES_WRITTEN_THAN_EXPECTED ;
  260.  
  261.    END ;  {  IndexWrite  }
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  FUNCTION    SearchIndex ( VAR f                 : IFile ;
  268.                                index             : IndexStr ;
  269.                            VAR indexPosition     : LONGINT )
  270.                                                  : LONGINT ;
  271.   VAR
  272.        highRecord                                : LONGINT ;
  273.        lowRecord                                 : LONGINT ;
  274.        tempSearch                                : LONGINT ;
  275.        indexNotFound                             : BOOLEAN ;
  276.        tempIndex                                 : IndexType ;
  277.  
  278.    BEGIN  {  SearchIndex  }
  279.  
  280.      highRecord := IndexFileSize ( f.indexFile ) ;
  281.  
  282.      IF ( highRecord < 1 )
  283.       THEN
  284.        BEGIN
  285.  
  286.          SearchIndex := -1 ;
  287.  
  288.          Exit ;
  289.  
  290.        END ;  {  IF  }
  291.  
  292.      IF ( highRecord = 1 )
  293.       THEN
  294.        BEGIN
  295.  
  296.          indexPosition := 0 ;
  297.  
  298.          IndexSeek ( f.indexFile , indexPosition ) ;
  299.  
  300.          IndexRead ( f.indexFile , tempIndex ) ;
  301.  
  302.          IF ( tempIndex.index = index )
  303.           THEN
  304.              SearchIndex := tempIndex.position
  305.  
  306.           ELSE
  307.              SearchIndex := -1 ;
  308.  
  309.          Exit ;
  310.  
  311.        END ;  {  IF  }
  312.  
  313.      indexNotFound := TRUE ;
  314.  
  315.      lowRecord := 0 ;
  316.  
  317.      Dec ( highRecord ) ;                {  record position filesize - 1  }
  318.  
  319.      indexPosition := Trunc ( ( highRecord - lowRecord  ) / 2 ) ;
  320.  
  321.      WHILE (
  322.                   ( indexNotFound )
  323.              AND
  324.                   ( lowRecord <> highRecord )
  325.            )
  326.       DO
  327.        BEGIN
  328.  
  329.          IndexSeek ( f.indexFile , indexPosition ) ;
  330.  
  331.          IndexRead ( f.indexFile , tempIndex ) ;
  332.  
  333.          IF ( tempIndex.index = index )
  334.           THEN
  335.              indexNotFound := FALSE
  336.  
  337.           ELSE
  338.              IF ( tempIndex.index > index )
  339.               THEN
  340.                BEGIN
  341.  
  342.                  IF ( highRecord = indexPosition )
  343.                   THEN
  344.                      lowRecord := highRecord
  345.  
  346.                   ELSE
  347.                    BEGIN
  348.  
  349.                      highRecord := indexPosition ;
  350.  
  351.                      indexPosition :=
  352.                         lowRecord +
  353.                         Trunc ( ( highRecord - lowRecord ) / 2 ) ;
  354.  
  355.                    END ;  {  ELSE  }
  356.  
  357.                END    {  IF  }
  358.  
  359.               ELSE
  360.                BEGIN
  361.  
  362.                  IF ( lowRecord = indexPosition )
  363.                   THEN
  364.                      highRecord := lowRecord
  365.  
  366.                   ELSE
  367.                    BEGIN
  368.  
  369.                      lowRecord  := indexPosition ;
  370.  
  371.                      indexPosition :=
  372.                         lowRecord +
  373.                         Round ( ( highRecord - lowRecord ) / 2 ) ;
  374.  
  375.                    END ;  {  ELSE  }
  376.  
  377.                END ;  {  ELSE  }
  378.  
  379.        END ;  {  WHILE  }
  380.  
  381.      IF ( indexNotFound )
  382.       THEN
  383.          SearchIndex := -1
  384.  
  385.       ELSE
  386.          SearchIndex := tempIndex.position ;
  387.  
  388.    END ;  {  SearchIndex  }
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  FUNCTION    FileSizeIndexed ( VAR f             : IFile ;
  395.                                    size          : WORD )
  396.                                                  : LONGINT ;
  397.    BEGIN  {  FileSizeIndexed  }
  398.  
  399.      fileError := NO_ERROR ;
  400.  
  401.      FileSizeIndexed := ( FileSize ( f.baseFile ) DIV size ) ;
  402.  
  403.    END ;  {  FileSizeIndexed  }
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  PROCEDURE   InsertIndex ( VAR f                 : IFile ;
  410.                                index             : IndexStr ;
  411.                                position          : LONGINT ) ;
  412.  
  413.   VAR
  414.        newIndex                                  : IndexType ;
  415.        numWritten                                : WORD ;
  416.  
  417.        highRecord                                : LONGINT ;
  418.        lowRecord                                 : LONGINT ;
  419.        searchRecord                              : LONGINT ;
  420.        tempSearch                                : LONGINT ;
  421.        tempIndex                                 : IndexType ;
  422.  
  423.    BEGIN  {  InsertIndex  }
  424.  
  425.      newIndex.index         := index ;
  426.      newIndex.position      := position ;
  427.  
  428.      highRecord := IndexFileSize ( f.indexFile ) ;
  429.  
  430.      IF ( highRecord < 1 )
  431.       THEN
  432.        BEGIN
  433.  
  434.          IndexSeek ( f.indexFile , highRecord ) ;
  435.  
  436.          IndexWrite ( f.indexFile , newIndex ) ;
  437.  
  438.          Exit ;
  439.  
  440.        END ;  {  IF  }
  441.  
  442.      IF ( highRecord <= 1 )
  443.       THEN
  444.        BEGIN
  445.  
  446.          IndexSeek ( f.indexFile , 0 ) ;
  447.  
  448.          IndexRead ( f.indexFile , tempIndex ) ;
  449.  
  450.          IF ( tempIndex.index < newIndex.index )
  451.           THEN
  452.              IndexWrite ( f.indexFile , newIndex )
  453.  
  454.           ELSE
  455.              InsertRecord ( f.indexFile ,
  456.                             newIndex , 0 , SizeOf ( newIndex ) ) ;
  457.  
  458.          Exit ;
  459.  
  460.        END ;  {  IF  }
  461.  
  462.      IF ( highRecord <= 2 )
  463.       THEN
  464.        BEGIN
  465.  
  466.          IndexSeek ( f.indexFile , 0 ) ;
  467.  
  468.          IndexRead ( f.indexFile , tempIndex ) ;
  469.  
  470.          IF ( tempIndex.index > newIndex.index )
  471.           THEN
  472.            BEGIN
  473.  
  474.              InsertRecord ( f.indexFile ,
  475.                             newIndex , 0 , SizeOf ( newIndex ) ) ;
  476.  
  477.              Exit ;
  478.  
  479.            END ;  {  THEN  }
  480.  
  481.          IndexSeek ( f.indexFile , 1 ) ;
  482.  
  483.          IndexRead ( f.indexFile , tempIndex ) ;
  484.  
  485.          IF ( tempIndex.index > newIndex.index )
  486.           THEN
  487.            BEGIN
  488.  
  489.              InsertRecord ( f.indexFile ,
  490.                             newIndex , 1 , SizeOf ( newIndex ) ) ;
  491.  
  492.              Exit ;
  493.  
  494.            END ;  {  THEN  }
  495.  
  496.          IndexSeek ( f.indexFile , 2 ) ;
  497.  
  498.          IndexWrite ( f.indexFile , newIndex ) ;
  499.  
  500.          Exit ;
  501.  
  502.        END ;  {  IF  }
  503.  
  504.      lowRecord := 0 ;
  505.  
  506.      Dec ( highRecord ) ;                {  record position filesize - 1  }
  507.  
  508.      searchRecord := Trunc ( ( highRecord - lowRecord  ) / 2 ) ;
  509.  
  510.      WHILE ( ( ( highRecord - 1 ) > searchRecord ) AND
  511.              ( ( lowRecord + 1  ) < searchRecord ) )
  512.       DO
  513.        BEGIN
  514.  
  515.          IndexSeek ( f.indexFile , searchRecord ) ;
  516.  
  517.          IndexRead ( f.indexFile , tempIndex ) ;
  518.  
  519.          IF ( tempIndex.index > newIndex.index )
  520.           THEN
  521.            BEGIN
  522.  
  523.              IF ( highRecord = searchRecord )
  524.               THEN
  525.                  lowRecord := highRecord
  526.  
  527.               ELSE
  528.                BEGIN
  529.  
  530.                  highRecord := searchRecord ;
  531.  
  532.                  searchRecord :=
  533.                     lowRecord +
  534.                     Trunc ( ( highRecord - lowRecord ) / 2 ) ;
  535.  
  536.                END ;  {  ELSE  }
  537.  
  538.            END    {  IF  }
  539.  
  540.           ELSE
  541.            BEGIN
  542.  
  543.              IF ( lowRecord = searchRecord )
  544.               THEN
  545.                  highRecord := lowRecord
  546.  
  547.               ELSE
  548.                BEGIN
  549.  
  550.                  lowRecord  := searchRecord ;
  551.  
  552.                  searchRecord :=
  553.                     lowRecord +
  554.                     Round ( ( highRecord - lowRecord ) / 2 ) ;
  555.  
  556.                END ;  {  ELSE  }
  557.  
  558.            END ;  {  ELSE  }
  559.  
  560.         END ;  {  WHILE  }
  561.  
  562.       searchRecord := lowRecord ;
  563.  
  564.       REPEAT
  565.  
  566.         IndexSeek ( f.indexFile , searchRecord ) ;
  567.         IndexRead ( f.indexFile , tempIndex ) ;
  568.  
  569.         IF ( tempIndex.index < newIndex.index )
  570.          THEN
  571.             Inc ( searchRecord ) ;
  572.  
  573.       UNTIL ( ( tempIndex.index > newIndex.index ) OR
  574.               ( searchRecord > highRecord ) OR
  575.               ( searchRecord >= IndexFileSize ( f.indexfile ) ) ) ;
  576.  
  577.       InsertRecord ( f.indexFile ,
  578.                      newIndex , searchRecord , SizeOf ( newIndex ) )
  579.  
  580.    END ;  {  InsertIndex  }
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  PROCEDURE   ResetIndexed ( VAR f                : IFile ) ;
  587.  
  588.    BEGIN  {  ResetIndexed  }
  589.  
  590.      Reset ( f.baseFile , 1 ) ;
  591.      Reset ( f.indexFile , 1 ) ;
  592.  
  593.      fileError := NO_ERROR ;
  594.  
  595.    END ;  {  ResetIndexed  }
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  PROCEDURE   ReWriteIndexed ( VAR f              : IFile ) ;
  602.  
  603.    BEGIN  {  ReWriteIndexed  }
  604.  
  605.      ReWrite ( f.baseFile , 1 ) ;
  606.      ReWrite ( f.indexFile , 1 ) ;
  607.  
  608.      fileError := NO_ERROR ;
  609.  
  610.    END ;  {  ReWriteIndexed  }
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  PROCEDURE   SeekIndexed ( VAR f                 : IFile ;
  617.                                position          : LONGINT ;
  618.                                size              : WORD ) ;
  619.  
  620.    BEGIN  {  SeekIndexed  }
  621.  
  622.      fileError := NO_ERROR ;
  623.  
  624.      Seek ( f.baseFile , ( position * size ) ) ;
  625.  
  626.    END ;  {  SeekIndexed  }
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  PROCEDURE   ReadIndexed ( VAR f                 : IFile ;
  633.                            VAR buffer                    ;
  634.                                size              : WORD ) ;
  635.  
  636.   VAR
  637.        position                                  : LONGINT ;
  638.        index                                     : IndexStr
  639.                                                      ABSOLUTE
  640.                                                      BUFFER ;
  641.        numRead                                   : WORD ;
  642.        indexPosition                             : LONGINT ;
  643.  
  644.    BEGIN  {  ReadIndexed  }
  645.  
  646.      fileError := NO_ERROR ;
  647.  
  648.      position := SearchIndex ( f , index , indexPosition ) ;
  649.  
  650.      IF ( position < 0 )
  651.       THEN
  652.        BEGIN
  653.  
  654.          fileError := INDEX_NOT_FOUND ;
  655.  
  656.          Exit ;
  657.  
  658.        END ;  {  IF  }
  659.  
  660.      SeekIndexed ( f , position , size ) ;
  661.  
  662.      BlockRead ( f.baseFile , buffer , size , numRead ) ;
  663.  
  664.      IF ( numRead < size )
  665.       THEN
  666.          fileError := READ_LESS_BYTES_THAN_EXPECTED ;
  667.  
  668.    END ;  {  ReadIndexed  }
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  FUNCTION    IndexFilePos ( VAR f                : FILE )
  675.                                                  : LONGINT ;
  676.  
  677.    BEGIN  {  IndexFilePos  }
  678.  
  679.      IndexFilePos := FilePos ( f ) DIV SizeOf ( IndexType ) ;
  680.  
  681.    END ;  {  IndexFilePos  }
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  PROCEDURE   WriteIndexed ( VAR f                : IFile ;
  688.                             VAR buffer                   ;
  689.                                 size             : WORD ) ;
  690.  
  691.   VAR
  692.        position                                  : LONGINT ;
  693.        index                                     : IndexStr
  694.                                                      ABSOLUTE
  695.                                                      BUFFER ;
  696.        numWritten                                : WORD ;
  697.        indexPosition                             : LONGINT ;
  698.  
  699.    BEGIN  {  WriteIndexed  }
  700.  
  701.      fileError := NO_ERROR ;
  702.  
  703.      position := SearchIndex ( f , index , indexPosition ) ;
  704.  
  705.      IF ( position >= 0 )
  706.       THEN
  707.        BEGIN
  708.  
  709.          SeekIndexed ( f , position , size ) ;
  710.  
  711.          BlockWrite ( f.baseFile , buffer , size , numWritten ) ;
  712.  
  713.          IF ( numWritten < size )
  714.           THEN
  715.              fileError := LESS_BYTES_WRITTEN_THAN_EXPECTED ;
  716.  
  717.          Exit ;
  718.  
  719.        END ; {  IF  }
  720.  
  721.      SeekIndexed ( f , FileSizeIndexed ( f , size ) , size ) ;
  722.  
  723.      BlockWrite ( f.baseFile , buffer , size , numWritten ) ;
  724.  
  725.      IF ( numWritten < size )
  726.       THEN
  727.          fileError := LESS_BYTES_WRITTEN_THAN_EXPECTED ;
  728.  
  729.      InsertIndex ( f , index , FilePosIndexed ( f , size ) - 1 ) ;
  730.  
  731.    END ;  {  WriteIndexed  }
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  PROCEDURE   CloseIndexed ( VAR f                : IFile ) ;
  738.  
  739.    BEGIN  {  CloseIndexed  }
  740.  
  741.      fileError := NO_ERROR ;
  742.  
  743.      Close ( f.baseFile ) ;
  744.      Close ( f.indexFile ) ;
  745.  
  746.    END ;  {  CloseIndexed  }
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  FUNCTION    FilePosIndexed ( VAR f              : IFile ;
  753.                                   size           : WORD )
  754.                                                  : LONGINT ;
  755.  
  756.    BEGIN  {  FilePosIndexed  }
  757.  
  758.      fileError := NO_ERROR ;
  759.  
  760.      FilePosIndexed := FilePos ( f.baseFile ) DIV size ;
  761.  
  762.    END ;  {  FilePosIndexed  }
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  PROCEDURE   AssignIndexed ( VAR f               : IFile ;
  769.                                  indexFile       : STRING ) ;
  770.  
  771.   CONST
  772.        INDEX_EXT                                 = 'IDX' ;
  773.        FILE__EXT                                 = 'FIL' ;
  774.  
  775.   VAR
  776.        dotPosition                               : BYTE ;
  777.  
  778.    BEGIN  {  AssignIndexed  }
  779.  
  780.      fileError := NO_ERROR ;
  781.  
  782.      IF ( indexFile = '' )
  783.       THEN
  784.        BEGIN
  785.  
  786.          fileError := INVALID_FILE_NAME ;
  787.  
  788.        END ;  {  IF  }
  789.  
  790.      dotPosition := Pos ( '.' , indexFile ) ;
  791.  
  792.      IF ( dotPosition <> 0 )
  793.       THEN
  794.        BEGIN
  795.  
  796.          fileError := INVALID_FILE_NAME ;
  797.  
  798.          Exit ;
  799.  
  800.        END ;  {  IF  }
  801.  
  802.      Assign ( f.indexFile ,    indexFile + '.' + INDEX_EXT ) ;
  803.      Assign ( f.baseFile ,     indexFile + '.' + FILE__EXT ) ;
  804.  
  805.      f.fileName := indexFile ;
  806.  
  807.  
  808.    END ;  {  AssignIndexed  }
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  PROCEDURE   DeleteIndexed ( VAR f               : IFile ;
  815.                              VAR buffer          ;
  816.                                  size            : WORD ) ;
  817.  
  818.   VAR
  819.        position                                  : LONGINT ;
  820.        index                                     : IndexStr
  821.                                                      ABSOLUTE
  822.                                                      BUFFER ;
  823.        numWritten                                : WORD ;
  824.        indexPosition                             : LONGINT ;
  825.        tempIndex                                 : IndexType ;
  826.  
  827.    BEGIN  {  DeleteIndexed  }
  828.  
  829.      fileError := NO_ERROR ;
  830.  
  831.      position := SearchIndex ( f , index , indexPosition ) ;
  832.  
  833.      IF ( position < 0 )
  834.       THEN
  835.        BEGIN
  836.  
  837.          fileError := INDEX_NOT_FOUND ;
  838.  
  839.          Exit ;
  840.  
  841.        END ; {  IF  }
  842.  
  843.      DeleteRecord ( f.baseFile , position , size ) ;
  844.  
  845.      DeleteRecord ( f.indexFile , indexPosition , SizeOf ( IndexType ) ) ;
  846.  
  847.      IndexReset ( f.indexFile ) ;
  848.  
  849.      WHILE ( NOT ( EOF ( f.indexFile ) ) )
  850.       DO
  851.        BEGIN
  852.  
  853.          IndexRead ( f.indexFile , tempIndex ) ;
  854.  
  855.          IF ( tempIndex.position > indexPosition )
  856.           THEN
  857.            BEGIN
  858.  
  859.              Dec ( tempIndex.position ) ;
  860.  
  861.              IndexSeek ( f.indexFile , IndexFilePos ( f.indexFile ) - 1 ) ;
  862.  
  863.              IndexWrite ( f.indexFile , tempIndex ) ;
  864.  
  865.            END ;  {  THEN  }
  866.  
  867.        END ;  {  WHILE  }
  868.  
  869.    END ;  {  DeleteIndexed  }
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  FUNCTION    IndexedError (     errorNum         : WORD )
  876.                                                  : STRING ;
  877.  
  878.    BEGIN  {  IndexedError  }
  879.  
  880.      CASE errorNum
  881.       OF
  882.  
  883.          NO_ERROR                         :
  884.             IndexedError := 'no error' ;
  885.  
  886.          NOT_ENOUGH_MEMORY                :
  887.             IndexedError := 'not enough memory to complete operation' ;
  888.  
  889.          READ_LESS_BYTES_THAN_EXPECTED    :
  890.             IndexedError := 'file read error' ;
  891.  
  892.          INDEX_NOT_FOUND                  :
  893.             IndexedError := 'index was not found' ;
  894.  
  895.          LESS_BYTES_WRITTEN_THAN_EXPECTED :
  896.             IndexedError := 'file write error' ;
  897.  
  898.          INVALID_FILE_NAME                :
  899.             IndexedError := 'file name invalid' ;
  900.  
  901.       ELSE
  902.  
  903.          IndexedError := 'FATAL ERROR!!  Unknown  error!' ;
  904.  
  905.          END ;  {  CASE errorNum  }
  906.  
  907.      END ;  {  IndexedError  }
  908.  
  909.  
  910.  
  911.  
  912.  
  913. BEGIN
  914.  
  915.   fileError      := 0 ;
  916.  
  917. END .